package linker.window;

import linker.account.Account;
import linker.account.ManageAccount; 
import linker.chat.ChatCell;
import linker.debug.OutputWindow;
import linker.debug.ErrWindow;
import linker.list.CellRender;
import linker.list.Model;
import linker.plugin.PluginManager;
import linker.file.FileManager;
import linker.setting.SettingWindow;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.PrintStream;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;



import org.jivesoftware.smack.packet.Presence;

/**
 * 
 * @version linker 0.93
 * @author Jianfeng jianfeng.linker@gmail.com
 * 
 */

public class MainWindow extends JFrame implements ActionListener, MouseListener {
	private static final long serialVersionUID = 1L;

	private JList viewList;

	private JLabel listLabel;

	private JLabel statusLabel;

	private JTextField statusField = new JTextField(10);

	private TrayIcon trayIcon;

	private JPanel userPanel;

	private JLabel statusBox;

	private JCheckBox debugWindow;

	private FilterField searchField;

	private String imageDirPath;

	private JPopupMenu statusMenu;

	private Presence.Mode mode = Presence.Mode.available;

	public MainWindow() {
		super("Linker");
		setName("MainWindow");

		imageDirPath = ManageAccount.getImagePath();
		setIconImage(Toolkit.getDefaultToolkit().createImage(
				imageDirPath + "logo.ico"));
		Account.getAccount().setMainWindow(this);

		Container container = getContentPane();

		// Menu bar
		JMenuBar menubar = new JMenuBar();
		JMenu menu = new JMenu("Setting");
		JMenuItem item = new JMenuItem("Settings");
		item.setEnabled(false);
		item.addActionListener(this);
		menu.add(item);
		item = new JMenuItem("Plugins");
		item.addActionListener(this);
		menu.add(item);
		item = new JMenuItem("File Manager");
		item.addActionListener(this);
		menu.add(item);
		menu.add(new JSeparator());

		item = new JMenuItem("Buddy list");
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B,
				ActionEvent.ALT_MASK));
		menu.add(item);

		item = new JMenuItem("Message list");
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M,
				ActionEvent.ALT_MASK));
		menu.add(item);

		item = new JMenuItem("Function list");
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
				ActionEvent.ALT_MASK));
		menu.add(item);
		menubar.add(menu);

		menu = new JMenu("About");
		debugWindow = new JCheckBox("Debug window", false);
		debugWindow.setEnabled(false);
		debugWindow.addActionListener(this);
		menu.add(debugWindow);
		menu.add(new JSeparator());
		item = new JMenuItem("About");
		item.addActionListener(this);
		menu.add(item);
		menubar.add(menu);
		setJMenuBar(menubar);

		statusMenu = new JPopupMenu();
		JMenuItem statusItem = new JMenuItem("Online");
		statusItem.setIcon(ChatCell.freeIcon);
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);
		statusItem = new JMenuItem("Busy");
		statusItem.setIcon(ChatCell.busyIcon);
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);
		statusItem = new JMenuItem("Away");
		statusItem.setIcon(ChatCell.awayIcon);
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);

		// User panel
		userPanel = new JPanel();
		userPanel.setLayout(new BorderLayout());
		statusBox = new JLabel();
		statusBox.setIcon(ChatCell.freeIcon);
		statusBox.addMouseListener(this);
		userPanel.add(statusBox, BorderLayout.WEST);
		statusLabel = new JLabel("Online");
		statusLabel.addMouseListener(this);
		statusField.addActionListener(this);
		statusField.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				if (statusField.getText().trim().length() == 0)
					return;
				statusLabel.setText(statusField.getText());
				userPanel.add(statusLabel, BorderLayout.CENTER);
				userPanel.remove(statusField);
				userPanel.updateUI();
				Account.sendPacket(new Presence(Presence.Type.available,
						statusField.getText(), 24, mode));
			}
		});
		userPanel.add(statusLabel, BorderLayout.CENTER);
		container.add(userPanel, BorderLayout.NORTH);

		JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new BorderLayout());
		viewList = new JList();
		viewList.setModel(Account.getBuddyList());
		CellRender cellRender = new CellRender();
		viewList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		viewList.setCellRenderer(cellRender);
		new ViewListListener(viewList);
		centerPanel.add(new JScrollPane(viewList), BorderLayout.CENTER);

		// Search field
		searchField = new FilterField(10, viewList);
		searchField.addActionListener(this);
		centerPanel.add(searchField, BorderLayout.NORTH);
		container.add(centerPanel, BorderLayout.CENTER);

		// Status label
		listLabel = new JLabel("You have 0 message");
		listLabel.addMouseListener(this);
		container.add(listLabel, BorderLayout.SOUTH);

		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				if (SystemTray.isSupported())
					setVisible(false);
				else {
					Account.disconnect();
					System.exit(0);
				}

			}
		});

		initTrayIcon();
		minimizeToTray();

		setSize(200, 476);
		setLocationRelativeTo(null);
		try {
			WindowSaver.getWindowSaver().loadSettings(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
		setVisible(true);
	}

	private void initTrayIcon() {
		Image image = Toolkit.getDefaultToolkit().createImage(
				imageDirPath + "logo0.png");

		PopupMenu popup = new PopupMenu();
		final MenuItem showItem = new MenuItem("Show");
		final MenuItem exitItem = new MenuItem("Exit");
		ActionListener showListener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == exitItem) {
					System.exit(0);
					Account.disconnect();
				} else
					setVisible(!isVisible());
			}
		};
		showItem.addActionListener(showListener);
		exitItem.addActionListener(showListener);

		popup.add(showItem);
		popup.add(exitItem);

		trayIcon = new TrayIcon(image, "Linker", popup);
		trayIcon.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 1)
					setVisible(!isVisible());
			}

		});
	}

	protected void minimizeToTray() {
		SystemTray tray = SystemTray.getSystemTray();
		try {
			trayIcon.setImageAutoSize(true);
			tray.add(trayIcon);
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	public void actionPerformed(ActionEvent e) {

		if (e.getActionCommand() == "About") {
			new AboutWindow();
		} else if (e.getSource() == statusField) {
			statusLabel.setText(statusField.getText());
			userPanel.remove(statusField);
			userPanel.add(statusLabel, BorderLayout.CENTER);
			userPanel.updateUI();
		} else if (e.getActionCommand() == "Message list")
			changeListModel(Account.getMessageList());
		else if (e.getActionCommand() == "Plugins")
			PluginManager.getPluginManager().setVisible(true);
		else if (e.getActionCommand() == "Settings")
			SettingWindow.getSettingWindow().setVisible(true);
		else if (e.getActionCommand() == "File Manager")
			FileManager.getFileManager().setVisible(true);
		else if (e.getActionCommand() == "Buddy list")
			changeListModel(Account.getBuddyList());
		else if (e.getActionCommand() == "Function list")
			changeListModel(Account.getFunctionList());
		else if (e.getSource() == searchField) {
			if (viewList.getModel().getSize() == 0) {
				((Model) viewList.getModel()).addElement(searchField.getText());
			}
		} else if (e.getSource() == debugWindow) {
			if (debugWindow.isSelected()) {
				System.setOut(new PrintStream(new OutputWindow()));
				System.setErr(new PrintStream(new ErrWindow()));
			} else {
				System.setOut(System.out);
				System.setErr(System.err);
			}
		} else if (e.getActionCommand() == "Online") {
			statusMenu.setVisible(false);
			Account.sendPacket(new Presence(Presence.Type.available,
					statusLabel.getText(), 24, Presence.Mode.available));
			statusBox.setIcon(ChatCell.freeIcon);
			mode = Presence.Mode.available;
		} else if (e.getActionCommand() == "Busy") {
			statusMenu.setVisible(false);
			Account.sendPacket(new Presence(Presence.Type.available,
					statusLabel.getText(), 24, Presence.Mode.dnd));
			statusBox.setIcon(ChatCell.busyIcon);
			mode = Presence.Mode.dnd;
		} else if (e.getActionCommand() == "Away") {
			statusMenu.setVisible(false);
			Account.sendPacket(new Presence(Presence.Type.available,
					statusLabel.getText(), 24, Presence.Mode.away));
			statusBox.setIcon(ChatCell.awayIcon);
			mode = Presence.Mode.away;
		}

	}

	private void changeListModel(ListModel listModel) {
		viewList.setModel(listModel);

		setStatus();
	}

	public void changeList() {
		if (viewList.getModel() == Account.getBuddyList())
			viewList.setModel(Account.getMessageList());
		else if (viewList.getModel() == Account.getMessageList())
			viewList.setModel(Account.getFunctionList());
		else
			viewList.setModel(Account.getBuddyList());

		setStatus();
	}

	public void setStatus() {
		int n = Account.getMessageList().size();
		String imagePath;

		listLabel.setText("You have " + n + (n > 1 ? " messages" : " message"));

		if (n == 0)
			imagePath = imageDirPath + "logo0.png";
		else if (n == 1)
			imagePath = imageDirPath + "logo.png";
		else if (n == 2)
			imagePath = imageDirPath + "logo2.png";
		else if (n == 3)
			imagePath = imageDirPath + "logo3.png";
		else
			imagePath = imageDirPath + "logo4.png";

		trayIcon.setImage(Toolkit.getDefaultToolkit().createImage(imagePath));
	}

	public void mouseClicked(MouseEvent e) {

		if (e.getSource() == listLabel)
			changeList();
		else if (e.getSource() == statusLabel) {

			statusField.setText(statusLabel.getText());
			userPanel.add(statusField, BorderLayout.CENTER);
			userPanel.remove(statusLabel);
			userPanel.updateUI();

			statusField.requestFocus();
			statusField.selectAll();
		} else if (e.getSource() == statusBox) {

			if (e.getClickCount() > 1 || e.getButton() != MouseEvent.BUTTON1)
				return;

			statusMenu.setLocation(e.getLocationOnScreen());
			statusMenu.setVisible(true);
		}

	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

}
